<?php

namespace magein\utils;

class Faker
{
    /**
     * @param array $data
     * @return string
     */
    public static function random(array $data): string
    {
        $len = count($data);
        if ($len > 0) {
            return $data[rand(0, count($data) - 1)];
        }
        return '';
    }

    /**
     * 生成姓名
     * @return string
     */
    public static function name(): string
    {
        $xing = [
            '陈', '李', '黄', '张', '梁', '林', '刘', '吴', '罗', '杨', '陈', '王', '李', '吴', '符', '林', '黄', '张', '郑', '李', '陈', '刘', '王', '杨', '周', '黄', '罗', '唐', '马',
        ];

        $ming = [
            '达', '耀', '兴', '荣', '华', '旺', '盈', '丰', '余', '昌', '盛', '俊', '威', '英', '健', '壮', '焕', '挺', '帅', '秀', '伟', '武', '雄', '巍', '松', '柏', '山', '石', '婵', '娟', '姣', '妯', '婷', '姿', '媚', '婉', '丽', '妩', '美', '倩', '兰', '颖', '灵', '睿', '锐', '哲', '慧', '敦', '迪', '明', '晓', '显', '悉', '晰', '维', '学', '思', '悟', '析', '文', '书', '勤仁', '义', '礼', '智', '信', '德', '诚', '伦', '孝', '忠', '良', '勤', '俭', '廉', '文', '章', '斌'
        ];

        $len = rand(1, 2);

        $name = self::random($xing);

        for ($i = 0; $i < $len; $i++) {
            $name .= self::random($ming);
        }

        return $name;
    }

    /**
     * 邮箱地址
     * @return string
     */
    public static function email(): string
    {
        $account = rand(10000, 99999999);
        $platform = self::random([
            '163.com',
            'gmail.com',
            'hotmail.com',
            'sina.com',
            'sohu.com',
            'tom.com',
            'qq.com',
            'yahoo.com'
        ]);
        return sprintf('%s@%s', $account, $platform);
    }

    /**
     * 生成手机号码
     * @return string
     */
    public static function phone(): string
    {
        $numbers = [
            '31',
            '35',
            '37',
            '38',
            '39',
            '50',
            '51',
            '55',
            '57',
            '59',
            '80',
            '81',
            '87',
            '88',
            '89',
            '91',
            '99',
        ];

        return '1' . self::random($numbers) . rand(1000, 9999) . rand(1000, 9999);
    }

    /**
     * 生成性别
     * @return int
     */
    public static function sex(): int
    {
        return rand(0, 2);
    }

    /**
     * 生成状态
     * @return int
     */
    public static function status(): int
    {
        return rand(0, 1);
    }

    /**
     * 兴趣爱好
     * @return array
     */
    public static function favorite(): array
    {
        $favorite = [
            '阅读小说',
            '热爱运动健身',
            '绘画和手工艺',
            '热爱旅行探索世界',
            '听音乐和唱歌',
            '热爱摄影记录生活',
            '烹饪和烘焙美食',
            '热爱园艺和植物养护',
            '看电影和追剧',
            '热爱学习新知识和技能',
            '与朋友聚会交流',
            '热爱宠物和动物饲养',
            '阅读历史和文学名著',
            '热爱学习和研究哲学',
            '听讲座和参加研讨会',
            '热爱写作和创作文学作品',
            '收藏邮票和硬币',
            '热爱阅读科幻和奇幻小说',
            '钓鱼和户外露营',
            '热爱学习外语和文化交流',
            '跳舞和参加舞蹈课程',
            '热爱旅行探索不同的城市和文化'
        ];

        $keys = array_rand($favorite, rand(2, 4));

        $result = [];
        foreach ($favorite as $key => $item) {
            if (in_array($key, $keys)) {
                $result[] = $item;
            }
        }

        return $result;
    }

    /**
     * 生成标题
     * @return string
     */
    public static function title(): string
    {
        $lists = [
            '金融科技的崛起与发展趋势',
            '区块链技术在金融领域的应用前景',
            '加密货币的原理与市场分析',
            '量化投资策略的原理与实践',
            '风险管理的挑战与方法论',
            '金融监管的改革与创新',
            '普惠金融的发展与影响',
            '绿色金融的前景与政策支持',
            '金融创新的案例与经验分享',
            '金融科技的伦理与法规探讨',
            '基因编辑技术的发展与应用',
            '精准医疗的前景与挑战',
            '远程医疗的优势与局限',
            '人工智能在医疗诊断中的应用',
            '健康管理的策略与实践',
            '心理健康的重要性与干预措施',
            '公共卫生政策的制定与实施',
            '疫苗研发的进展与挑战',
            '老龄化社会的健康问题与应对策略',
            '医疗技术的创新与伦理问题',
            '未来科技趋势预测',
            '人工智能在各行业的应用',
            '区块链技术的原理与前景',
            '大数据时代的挑战与机遇',
            '云计算的发展与影响',
            '物联网的安全与隐私挑战',
            '虚拟现实与增强现实的未来展望',
            '5G技术的商业应用与影响',
            '无人驾驶汽车的技术与挑战',
            '可穿戴设备的市场前景与趋势',
            '在线教育的优势与挑战',
            'K-12教育的创新与实践',
            'MOOC的发展与影响',
            '自适应学习技术的应用',
            'STEM教育的实践与效果',
            '人工智能在教育中的应用',
            '学习能力的提升方法与技巧',
            '在线学习的评估与反馈机制',
            '教育公平性的探索与实践',
            '职业教育的现状与未来趋势'
        ];

        return self::random($lists);
    }

    /**
     * 生成text
     * @return string
     */
    public static function text(): string
    {
        $lists = [
            '今天的天空格外蓝',
            '窗外的鸟儿叫得很欢快',
            '突然下起了小雨',
            '阳光透过云层洒下温暖',
            '街头的咖啡香味让人心情愉悦',
            '不经意间发现了一首好歌',
            '突然想吃冰淇淋',
            '今天的电影很精彩',
            '与朋友聊天时发现了一个有趣的观点',
            '在公园散步时感受到了大自然的宁静',
            '不经意间看到了一个美丽的日落',
            '突然想起了一件小时候的趣事',
            '在书店里发现了一本好书',
            '与家人共度了一个愉快的晚餐时光',
            '在公园里放风筝感觉非常自由',
            '突然想去远足探索未知的风景',
            '与朋友一起打篮球时感受到了运动的快乐',
            '在海边散步时听到了海浪的声音',
            '突然想学习一门新技能',
            '在图书馆里找到了一个安静的角落读书',
            '不经意间听到了一个令人振奋的消息',
            '与同事合作完成了一项任务感觉非常有成就感',
            '在公园里散步时感受到了春天的气息',
            '突然想去旅行探索不同的文化和风景',
            '与家人一起做家务时感受到了亲情的温暖',
            '在咖啡馆里遇到了一位有趣的陌生人',
            '突然想尝试一种新的美食',
            '在书店里遇到了一个志同道合的朋友'
        ];

        return self::random($lists);
    }

    /**
     * 随机字符串
     * @param int $length
     * @param int|null $type
     * @param string $add_chars
     * @return string
     */
    public static function str(int $length = 6, int $type = null, string $add_chars = ''): string
    {
        $str = '';
        switch ($type) {
            case 0:
                $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' . $add_chars;
                break;
            case 1:
                $chars = str_repeat('0123456789', 3);
                break;
            case 2:
                $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . $add_chars;
                break;
            case 3:
                $chars = 'abcdefghijklmnopqrstuvwxyz' . $add_chars;
                break;
            case 4:
                $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书" . $add_chars;
                break;
            default:
                $chars = 'ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789' . $add_chars;
                break;
        }
        if ($length > 10) {
            $chars = $type == 1 ? str_repeat($chars, $length) : str_repeat($chars, 5);
        }
        if ($type != 4) {
            $chars = str_shuffle($chars);
            $str = substr($chars, 0, $length);
        } else {
            for ($i = 0; $i < $length; $i++) {
                $str .= mb_substr($chars, floor(mt_rand(0, mb_strlen($chars, 'utf-8') - 1)), 1);
            }
        }
        return $str;
    }

    /**
     * @return string
     */
    public static function address(): string
    {
        $lists = [
            '北京市朝阳区建国路88号现代城A座',
            '上海市浦东新区张江高科技园区科苑路399号',
            '广州市天河区天河路385号太古汇商场',
            '深圳市南山区科技园路1001号腾讯大厦',
            '成都市武侯区人民南路四段3号来福士广场',
            '杭州市西湖区文三路477号华星科技大厦',
            '武汉市洪山区珞瑜路726号光谷世界城',
            '南京市鼓楼区中山北路1号紫峰大厦',
            '重庆市渝中区民族路188号环球金融中心',
            '西安市雁塔区长安中路123号赛格国际购物中心',
            '天津市和平区南京路189号津汇广场',
            '青岛市市南区香港中路8号中铁中心',
            '大连市中山区人民路23号鸿基大厦',
            '厦门市思明区湖滨南路819号宝福大厦',
            '长沙市芙蓉区五一大道635号7UP购物中心',
            '郑州市金水区花园路39号国贸360广场',
            '沈阳市和平区青年大街288号万象城',
            '长春市朝阳区重庆路1255号万达广场',
            '哈尔滨市南岗区西大直街118号松雷商业大厦',
            '石家庄市长安区中山东路326号北国商城',
            '太原市小店区长风街113号北美新天地',
            '济南市历下区泉城路188号恒隆广场',
            '合肥市蜀山区长江西路189号之心城',
            '南昌市东湖区中山路177号百货大楼',
            '福州市鼓楼区八一七北路268号东百中心',
            '昆明市五华区东风西路11号顺城购物中心',
            '贵阳市云岩区中华中路1号国贸广场',
            '南宁市青秀区民族大道136号万象城',
            '海口市龙华区国贸路26号宝华大厦',
            '兰州市城关区庆阳路488号万盛商务大厦'
        ];

        return self::random($lists);
    }

    /**
     * @param $attrs
     * @param callable|null $callback
     * @return array
     */
    public static function mock($attrs, callable $callback = null): array
    {
        $data = [];
        foreach ($attrs as $attr) {

            $field = $attr['Field'];
            $type = $attr['Type'];
            $comment = $attr['Comment'];
            if (in_array($field, ['id', 'deleted_at'])) {
                continue;
            } elseif (in_array($field, ['sort', 'order', 'age'])) {
                $data[$field] = rand(1, 99);
            } elseif (in_array($field, ['username', 'account'])) {
                $data[$field] = self::str(rand(4, 12));
            } elseif (in_array($field, ['email', 'mail'])) {
                $data[$field] = self::email();
            } elseif (in_array($field, ['name', 'nickname', 'nick', 'contact', 'contact_person', 'customer', 'customer_contact'])) {
                $data[$field] = self::name();
            } elseif ($field == 'title' || str_ends_with($field, '_title')) {
                $data[$field] = self::title();
            } elseif (in_array($field, ['phone', 'mobile', 'tel', 'contact_phone', 'contact_mobile'])) {
                $data[$field] = self::phone();
            } elseif (in_array($field, ['address', 'street', 'road', 'avenue', 'way'])) {
                $data[$field] = self::address();
            } elseif (in_array($field, ['ip', 'ipv4']) || str_contains($field, 'ip')) {
                $data[$field] = sprintf('%s.%s.%s.%s', rand(1, 255), rand(1, 255), rand(1, 255), rand(1, 255));
            } elseif (in_array($field, ['created_at', 'updated_at'])) {
                $data[$field] = date('Y-m-d H:i:s');
            } elseif (in_array($field, ['remark', 'content', 'message', 'notice', 'intro', 'desc', 'description'])) {
                $data[$field] = self::text();
            } elseif (str_ends_with($field, '_no')) {
                $len = str_replace(['char', '(', ')'], ['', '', ''], $type);
                $data[$field] = str_pad(date('YmdHis') . rand(1000, 9999), intval($len), '0');
            } elseif (str_ends_with($field, '_id')) {
                $data[$field] = rand(1, 99);
            } elseif ($type === 'datetime') {
                if (in_array($field, ['begin_time', 'start_time'])) {
                    $data[$field] = date('Y-m-d H:i:s');
                } elseif ($field === 'end_time') {
                    $month = rand(1, 6);
                    $data[$field] = date('Y-m-d H:i:s', strtotime('+' . $month . ' month'));
                } else {
                    $data[$field] = date('Y-m-d H:i:s');
                }
            } elseif ($type === 'date') {
                if (in_array($field, ['begin_time', 'start_time'])) {
                    $data[$field] = date('Y-m-d');
                } elseif ($field === 'end_time') {
                    $month = rand(1, 6);
                    $data[$field] = date('Y-m-d', strtotime('+' . $month . ' month'));
                } else {
                    $data[$field] = date('Y-m-d');
                }
            } elseif ($type === 'time') {
                $data[$field] = date('H:i:s');
            } elseif (str_starts_with($type, 'tinyint')) {
                preg_match_all('/(-?[0-9])/', $comment, $matches);
                $numbers = $matches[1] ?? [];
                if (empty($numbers)) {
                    $numbers = [0, 1];
                }
                $min = intval(min($numbers));
                $max = intval(max($numbers));
                $value = rand($min, $max);
                $data[$field] = $value;
            } elseif (str_contains($type, 'int')) {
                $data[$field] = rand(1, 9999);
            } elseif (str_starts_with($type, 'char')) {
                $len = (int)str_replace(['char', '(', ')'], ['', '', ''], $type);
                if ($len > 30) {
                    $len = 30;
                } elseif ($len <= 0) {
                    $len = 1;
                }
                $data[$field] = self::str($len);
            } elseif (str_starts_with($type, 'varchar')) {
                $len = (int)str_replace(['varchar', '(', ')'], ['', '', ''], $type);
                if ($len > 30) {
                    $len = 30;
                } elseif ($len <= 0) {
                    $len = 1;
                }
                $data[$field] = self::str($len);
            } elseif (str_ends_with($type, 'text')) {
                $data[$field] = self::text();
            }

            if ($callback) {
                $data[$field] = $callback($attr, $data[$field]);
            }
        }

        return $data;
    }
}